package com.sky.common.task;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.sky.business.sys.domain.CameraConfig;
import com.sky.business.sys.domain.SystemConfig;
import com.sky.business.sys.domain.TrackTask;
import com.sky.business.sys.event.EdgeEndTrackingEvent;
import com.sky.business.sys.service.CameraConfigService;
import com.sky.business.sys.service.SystemConfigService;
import com.sky.business.sys.service.TrackTaskService;
import com.sky.business.sys.util.MQTTClientUtils;
import com.sky.common.config.CacheConstants;
import com.sky.common.enums.TrackStatus;
import com.sky.common.track.DeviceStatus;
import com.sky.common.track.TrackTaskInfo;
import com.sky.common.track.TrackTaskManager;
import com.sky.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 结束跟踪定时任务,当任务在20秒内没有收到移动的beginTrack事件,自动下发结束任务
 *
 */
@Slf4j
@Component
public class EdgeDynamicEndTrackingTask {

    @Autowired
    private TrackTaskService trackTaskService;

    @Autowired
    private SystemConfigService systemConfigService;

    @Autowired
    private CameraConfigService cameraConfigService;

    public static ObjectMapper objectMapper = new ObjectMapper().setTimeZone(SimpleTimeZone.getTimeZone("GMT+8"));

    /**
     * 结束跟踪
     *
     * @param systemConfig 系统配置
     * @param taskId       任务id
     */
    public void endTrack(SystemConfig systemConfig, String taskId) {
        Date now = new Date();
        Set<String> deviceIdSet = new HashSet<>();
        List<TrackTask> trackTaskList = trackTaskService.findByTaskIdAndStatus(taskId, TrackStatus.TRACKING);
        for (TrackTask trackTask : trackTaskList) {
            //更新数据库
            trackTaskService.endTrack(trackTask, now);
            deviceIdSet.add(trackTask.getDeviceId());
        }
        //发送结束任务消息给终端
        for (String deviceId : deviceIdSet) {
            try {
                CameraConfig cameraConfig = cameraConfigService.findByDeviceId(deviceId);
                EdgeEndTrackingEvent edgeEndTrackingEvent = new EdgeEndTrackingEvent(systemConfig.getEdgeId(), deviceId, taskId);
                String responseMsg = objectMapper.writeValueAsString(edgeEndTrackingEvent);
                MQTTClientUtils.publish(MQTTClientUtils.LOCAL_MQTT_CLIENT, cameraConfig.getDispatcherTopic(), CacheConstants.DEFAULT_QOS, responseMsg);
            } catch (Exception e) {
                log.error("发送EndTracking消息发生异常, 任务ID:{}, 设备ID:{}", taskId, deviceId, e);
            }
        }
    }


    @Scheduled(cron = "*/20 * * * * ?")
    public void doTask() {
        SystemConfig systemConfig = systemConfigService.getSystemConfig();
        // 从数据库中查询所有未结束的任务
        List<TrackTask> trackingTaskList = trackTaskService.findByStatus(TrackStatus.TRACKING);
        Set<String> taskIdSet = trackingTaskList.stream().map(TrackTask::getTaskId).collect(Collectors.toSet());
        taskIdSet.addAll(TrackTaskManager.getTrackTaskIdSet());
        for (String taskId : taskIdSet) {
            try {
                boolean inactive = TrackTaskManager.inactive(taskId, CacheConstants.INACTIVE_SECOND_MAX);
                //如果任务不活跃则自动结束
                if (inactive) {
                    log.info("凌云平台连续{}秒没有下发追踪消息,停止任务. 任务ID:{}", CacheConstants.INACTIVE_SECOND_MAX, taskId);
                    endTrack(systemConfig, taskId);
                    TrackTaskManager.remove(taskId);
                }
            } catch (Exception e) {
                log.error("边缘中心自动结束追踪任务时发生异常,任务ID:{}", taskId, e);
            }
        }
    }

    @Scheduled(cron = "*/10 * * * * ?")
    public void releaseExpireStatusCamera() {
        SystemConfig systemConfig = systemConfigService.getSystemConfig();
        List<CameraConfig> cameraConfigList = cameraConfigService.list();
        for (CameraConfig cameraConfig : cameraConfigList) {
            DeviceStatus deviceStatus = TrackTaskManager.getDeviceStatus(cameraConfig.getCameraDeviceId());
            if (deviceStatus.getLastWorkState() != null && deviceStatus.getLastWorkState() == CacheConstants.BEGIN_TRACKING_WORK_STATE) {
                String taskId = deviceStatus.getLastTrackingTaskId();
                if (StringUtils.isNotEmpty(taskId)) {
                    List<TrackTask> trackTaskList = trackTaskService.findByTaskIdAndDeviceId(taskId, cameraConfig.getCameraDeviceId());
                    TrackTaskInfo trackTaskInfo = TrackTaskManager.getTrackTaskInfo(taskId);
                    if (trackTaskList.isEmpty() && trackTaskInfo == null) {
                        try {
                            log.warn("终端设备追踪任务已过期,强制停止.设备ID:{}, 任务ID:{}",cameraConfig.getCameraDeviceId(),taskId);
                            EdgeEndTrackingEvent edgeEndTrackingEvent = new EdgeEndTrackingEvent(systemConfig.getEdgeId(), cameraConfig.getCameraDeviceId(), taskId);
                            String responseMsg = objectMapper.writeValueAsString(edgeEndTrackingEvent);
                            MQTTClientUtils.publish(MQTTClientUtils.LOCAL_MQTT_CLIENT, cameraConfig.getDispatcherTopic(), CacheConstants.DEFAULT_QOS, responseMsg);
                        } catch (Exception e) {
                            log.error("边缘中心纠错终端设备发生异常", e);
                        }
                    }
                }
            }
        }
    }
}
